
class_name CBagItemArray
extends EventDispatcher

signal UUID_changed(old_value, new_value) 
signal MaskID_changed(old_value, new_value) 
signal ItemID_changed(old_value, new_value) 
signal ItemUUID_changed(old_value, new_value) 
signal ItemCount_changed(old_value, new_value) 
signal Int32Param1_changed(old_value, new_value) 
signal Int32Param2_changed(old_value, new_value) 
signal Int32Param3_changed(old_value, new_value) 
signal Int32Param4_changed(old_value, new_value) 
signal Int32Param5_changed(old_value, new_value) 
signal Int32Param6_changed(old_value, new_value) 
signal Uint8Param1_changed(old_value, new_value) 
signal Uint8Param2_changed(old_value, new_value) 
signal AttachAttrs_changed(old_value, new_value) 
signal CDEndTime_changed(old_value, new_value) 
signal ExpireTime_changed(old_value, new_value) 



class SBagItem:
    var nIndex
    var tblOwner
    var m_tblAlias
    var bInited = false
    func _init(owner):
        self.UUID = 0
        self.MaskID = owner and owner.m_UUID or 0
        self.ItemID = 0
        self.ItemUUID = 0
        self.ItemCount = 0
        self.Int32Param1 = 0	# 藏宝图为传送npc id
        self.Int32Param2 = 0	# 藏宝图传送npc线id
        self.Int32Param3 = 0	# 藏宝图开启的副本地图id
        self.Int32Param4 = 0	# 藏宝图传送npc x坐标
        self.Int32Param5 = 0	# 藏宝图传送npc y坐标
        self.Int32Param6 = 0	# 藏宝图为副本后的结束时间(秒)
        self.Uint8Param1 = 0	# 保险背包位置(下标从1开始)
        self.Uint8Param2 = 0	# 武器元素属性的Index, 默认0xff

        self.AttachAttrs = []
        self.AttachAttrs.resize(9)
        for i in range(9):
            self.AttachAttrs[i] = 0
        self.CDEndTime = 0	# CD结束时间
        self.ExpireTime = 0	# 限时物品过期时间

        self.nIndex = -1
        self.tblOwner = owner
        self.m_tblAlias = {
        Int32Param1 = [ "StrengthLv", "TreasureNpcNetID",  ],
        Int32Param2 = [ "EquipPet", "TreasureNpcLineID",  ],
        Int32Param3 = [ "StarLv", "TreasureNpcSceneID",  ],
        Int32Param4 = [ "Affix1", "TreasureNpcX",  ],
        Int32Param5 = [ "Affix2", "TreasureNpcY",  ],
        Int32Param6 = [ "BulletCount", "DungeonTime",  ],
        Uint8Param1 = [ "InsuranceBagSlot",  ],
        Uint8Param2 = [ "ElemProIndex",  ],
 
        }

    func GetIndex():
        return self.nIndex

    func SetZeroValue(owner):
        self.UUID = 0
        self.MaskID = owner and owner.m_UUID or 0
        self.ItemID = 0
        self.ItemUUID = 0
        self.ItemCount = 0
        self.Int32Param1 = 0	# 藏宝图为传送npc id
        self.Int32Param2 = 0	# 藏宝图传送npc线id
        self.Int32Param3 = 0	# 藏宝图开启的副本地图id
        self.Int32Param4 = 0	# 藏宝图传送npc x坐标
        self.Int32Param5 = 0	# 藏宝图传送npc y坐标
        self.Int32Param6 = 0	# 藏宝图为副本后的结束时间(秒)
        self.Uint8Param1 = 0	# 保险背包位置(下标从1开始)
        self.Uint8Param2 = 0	# 武器元素属性的Index, 默认0xff

        self.AttachAttrs = []
        self.AttachAttrs.resize(9)
        for i in range(9):
            self.AttachAttrs[i] = 0
        self.CDEndTime = 0	# CD结束时间
        self.ExpireTime = 0	# 限时物品过期时间


    func UnPack(_bufferStream, _bOffset):
        if _bOffset :
            _bufferStream.SetPosition(_bufferStream.GetPosition() + 4)

        self.UUID = _bufferStream.ReadInt64()
        self.MaskID = _bufferStream.ReadInt64()
        self.ItemID = _bufferStream.ReadInt32()
        self.ItemUUID = _bufferStream.ReadUint64()
        self.ItemCount = _bufferStream.ReadInt32()
        self.Int32Param1 = _bufferStream.ReadInt32()
        self.Int32Param2 = _bufferStream.ReadInt32()
        self.Int32Param3 = _bufferStream.ReadInt32()
        self.Int32Param4 = _bufferStream.ReadInt32()
        self.Int32Param5 = _bufferStream.ReadInt32()
        self.Int32Param6 = _bufferStream.ReadInt32()
        self.Uint8Param1 = _bufferStream.ReadUint8()
        self.Uint8Param2 = _bufferStream.ReadUint8()
        for i in range(TableCommonDefine.ECharLen.eCL_AttachAttrs):
            self.AttachAttrs[i-1] = _bufferStream.ReadUint32()
        self.CDEndTime = _bufferStream.ReadUint64()
        self.ExpireTime = _bufferStream.ReadUint64()

        self.bInited = true
        if self.tblOwner :
            self.tblOwner.DispatchEvent('uuid', [self, 0, self.nIndex])

    func CopyFrom(other):
        self.nIndex = other.nIndex
        self.ItemID = other.ItemID
        self.ItemUUID = other.ItemUUID
        self.ItemCount = other.ItemCount
        self.Int32Param1 = other.Int32Param1
        self.Int32Param2 = other.Int32Param2
        self.Int32Param3 = other.Int32Param3
        self.Int32Param4 = other.Int32Param4
        self.Int32Param5 = other.Int32Param5
        self.Int32Param6 = other.Int32Param6
        self.Uint8Param1 = other.Uint8Param1
        self.Uint8Param2 = other.Uint8Param2
        for i in range(9):
            self.AttachAttrs[i] = other.AttachAttrs[i]
        self.CDEndTime = other.CDEndTime
        self.ExpireTime = other.ExpireTime


    func Update(_bufferStream, _nIndex ):
        _bufferStream.SetPosition(_bufferStream.GetPosition() + 4)
        self.UUID = _bufferStream.ReadInt64()
        self.MaskID = _bufferStream.ReadInt64()
        self.ItemID = _bufferStream.ReadInt32()
        self.ItemUUID = _bufferStream.ReadUint64()
        self.ItemCount = _bufferStream.ReadInt32()
        self.Int32Param1 = _bufferStream.ReadInt32()
        self.Int32Param2 = _bufferStream.ReadInt32()
        self.Int32Param3 = _bufferStream.ReadInt32()
        self.Int32Param4 = _bufferStream.ReadInt32()
        self.Int32Param5 = _bufferStream.ReadInt32()
        self.Int32Param6 = _bufferStream.ReadInt32()
        self.Uint8Param1 = _bufferStream.ReadUint8()
        self.Uint8Param2 = _bufferStream.ReadUint8()
        var bChanged = false
        var newAttachAttrs = {}
        for i in range(TableCommonDefine.ECharLen.eCL_AttachAttrs):
            newAttachAttrs[i-1] = _bufferStream.ReadUint32()        
            if not bChanged and self.m_AttachAttrs[i] != newAttachAttrs[i]:
                bChanged = true
        var oldAttachAttrs = self.m_AttachAttrs
        self.m_AttachAttrs = newAttachAttrs
        if bChanged and self.tblOwner:
            self.tblOwner.DispatchEvent('AttachAttrs', [self, oldAttachAttrs, newAttachAttrs])
        self.CDEndTime = _bufferStream.ReadUint64()
        self.ExpireTime = _bufferStream.ReadUint64()


    func OnDataChanged( fieldName, oldValue, newValue ):
        if oldValue == newValue or not self.tblOwner:
            return
        self.tblOwner.emit_signal(fieldName, oldValue, newValue)


    #  SBagItem Geter Setter method # 
    var UUID:
        set(_value):
            var old = self.m_UUID
            self.UUID = _value
            if self.tblOwner:
                self.tblOwner.UUID_changed(old, _value)
        get:
            return UUID

    var MaskID:
        set(_value):
            var old = self.m_MaskID
            self.MaskID = _value
            if self.tblOwner:
                self.tblOwner.MaskID_changed(old, _value)
        get:
            return MaskID

    var ItemID:
        set(_value):
            var old = self.m_ItemID
            self.ItemID = _value
            if self.tblOwner:
                self.tblOwner.ItemID_changed(old, _value)
        get:
            return ItemID

    var ItemUUID:
        set(_value):
            var old = self.m_ItemUUID
            self.ItemUUID = _value
            if self.tblOwner:
                self.tblOwner.ItemUUID_changed(old, _value)
        get:
            return ItemUUID

    var ItemCount:
        set(_value):
            var old = self.m_ItemCount
            self.ItemCount = _value
            if self.tblOwner:
                self.tblOwner.ItemCount_changed(old, _value)
        get:
            return ItemCount

    var Int32Param1:
        set(_value):
            var old = self.m_Int32Param1
            self.Int32Param1 = _value
            if self.tblOwner:
                self.tblOwner.Int32Param1_changed(old, _value)
        get:
            return Int32Param1

    func GetStrengthLv():
        return self.m_Int32Param1

    func SetStrengthLv(_value):
        return self.SetInt32Param1(_value)

    func GetTreasureNpcNetID():
        return self.m_Int32Param1

    func SetTreasureNpcNetID(_value):
        return self.SetInt32Param1(_value)

    var Int32Param2:
        set(_value):
            var old = self.m_Int32Param2
            self.Int32Param2 = _value
            if self.tblOwner:
                self.tblOwner.Int32Param2_changed(old, _value)
        get:
            return Int32Param2

    func GetEquipPet():
        return self.m_Int32Param2

    func SetEquipPet(_value):
        return self.SetInt32Param2(_value)

    func GetTreasureNpcLineID():
        return self.m_Int32Param2

    func SetTreasureNpcLineID(_value):
        return self.SetInt32Param2(_value)

    var Int32Param3:
        set(_value):
            var old = self.m_Int32Param3
            self.Int32Param3 = _value
            if self.tblOwner:
                self.tblOwner.Int32Param3_changed(old, _value)
        get:
            return Int32Param3

    func GetStarLv():
        return self.m_Int32Param3

    func SetStarLv(_value):
        return self.SetInt32Param3(_value)

    func GetTreasureNpcSceneID():
        return self.m_Int32Param3

    func SetTreasureNpcSceneID(_value):
        return self.SetInt32Param3(_value)

    var Int32Param4:
        set(_value):
            var old = self.m_Int32Param4
            self.Int32Param4 = _value
            if self.tblOwner:
                self.tblOwner.Int32Param4_changed(old, _value)
        get:
            return Int32Param4

    func GetAffix1():
        return self.m_Int32Param4

    func SetAffix1(_value):
        return self.SetInt32Param4(_value)

    func GetTreasureNpcX():
        return self.m_Int32Param4

    func SetTreasureNpcX(_value):
        return self.SetInt32Param4(_value)

    var Int32Param5:
        set(_value):
            var old = self.m_Int32Param5
            self.Int32Param5 = _value
            if self.tblOwner:
                self.tblOwner.Int32Param5_changed(old, _value)
        get:
            return Int32Param5

    func GetAffix2():
        return self.m_Int32Param5

    func SetAffix2(_value):
        return self.SetInt32Param5(_value)

    func GetTreasureNpcY():
        return self.m_Int32Param5

    func SetTreasureNpcY(_value):
        return self.SetInt32Param5(_value)

    var Int32Param6:
        set(_value):
            var old = self.m_Int32Param6
            self.Int32Param6 = _value
            if self.tblOwner:
                self.tblOwner.Int32Param6_changed(old, _value)
        get:
            return Int32Param6

    func GetBulletCount():
        return self.m_Int32Param6

    func SetBulletCount(_value):
        return self.SetInt32Param6(_value)

    func GetDungeonTime():
        return self.m_Int32Param6

    func SetDungeonTime(_value):
        return self.SetInt32Param6(_value)

    var Uint8Param1:
        set(_value):
            var old = self.m_Uint8Param1
            self.Uint8Param1 = _value
            if self.tblOwner:
                self.tblOwner.Uint8Param1_changed(old, _value)
        get:
            return Uint8Param1

    func GetInsuranceBagSlot():
        return self.m_Uint8Param1

    func SetInsuranceBagSlot(_value):
        return self.SetUint8Param1(_value)

    var Uint8Param2:
        set(_value):
            var old = self.m_Uint8Param2
            self.Uint8Param2 = _value
            if self.tblOwner:
                self.tblOwner.Uint8Param2_changed(old, _value)
        get:
            return Uint8Param2

    func GetElemProIndex():
        return self.m_Uint8Param2

    func SetElemProIndex(_value):
        return self.SetUint8Param2(_value)

    var AttachAttrs:
        set(_value):
            var old = self.m_AttachAttrs
            self.AttachAttrs = _value
            if self.tblOwner:
                self.tblOwner.AttachAttrs_changed(old, _value)
        get:
            return AttachAttrs

    func GetAttachAttrsByIndex(_nIndex):
        return self.m_AttachAttrs[_nIndex]
    
    func SetAttachAttrsByIndex(_value,_nIndex):
        var old = self.m_AttachAttrs[_nIndex]    
        self.m_AttachAttrs[_nIndex] = _value
        # self.OnDataChanged( "AttachAttrs", _nIndex, [old, _value])
        # self.OnDataChanged( "AttachAttrs", old, _value, _nIndex )    
        return 13

    var CDEndTime:
        set(_value):
            var old = self.m_CDEndTime
            self.CDEndTime = _value
            if self.tblOwner:
                self.tblOwner.CDEndTime_changed(old, _value)
        get:
            return CDEndTime

    var ExpireTime:
        set(_value):
            var old = self.m_ExpireTime
            self.ExpireTime = _value
            if self.tblOwner:
                self.tblOwner.ExpireTime_changed(old, _value)
        get:
            return ExpireTime



# ================================= array ==========================
var m_UUID
var m_nBagItemCount
var m_BagItem

signal elem_update(array, old_value, new_value, index)
signal elem_add(array, old_value, new_value, index)
signal elem_del(array, old_value, new_value, index)

func _init( _uuid ):
    self.m_UUID = _uuid
    self.m_nBagItemCount = 0
    self.m_BagItem = []
    var nMaxIndex = self.GetBagItemMaxCount()-1
    self.m_BagItem.resize(nMaxIndex)
    for i in range(nMaxIndex):
        self.m_BagItem[i] = SBagItem.new(self) 
        self.m_BagItem[i].nIndex = i

func UnPack(_bufferStream):
    self.m_UUID = _bufferStream.ReadInt64()
    self.m_nBagItemCount = _bufferStream.ReadUint32()
    for i in range(self.m_nBagItemCount):
        var elem = SBagItem.new(self)
        elem.nIndex = i
        elem.UnPack(_bufferStream, false)
        self.m_BagItem[i] = elem

func GetTableName():
    return 'BagItem'

func GetUUID():
    return self.m_UUID

func GetBagItemCurNum():
    return self.m_nBagItemCount

func SetBagItemCurNum( nValue ):
    self.m_nBagItemCount = nValue

func SetCurNum(nValue):
    self.m_nBagItemCount = nValue

static func GetBagItemMaxCount():
    return TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM

func GetBagItemMaxNum():
    return TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM

func GetBagItem(_nIndex):
    if _nIndex < 0 or _nIndex >= TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM:
        print("GetBagItemEle _nIndex > TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM")
        return null

    return self.m_BagItem[_nIndex];

func SetBagItem(_Prop, _nIndex):
    if _nIndex < 0 or _nIndex >= TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM:
        print("SetBagItemEle _nIndex > TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM")
        return null
    
    var old = self.m_BagItem[_nIndex]
    var elem = SBagItem.new(self)
    elem.CopyFrom(_Prop)
    elem.nIndex = _nIndex
    self.m_BagItem[_nIndex] = elem
    elem_update.emit(self, old, elem, _nIndex)
    return elem


func AddBagItem(_Prop, _nIndex):
    var nCurNum = self.m_nBagItemCount
    if _nIndex < 0 or _nIndex > nCurNum:
        _nIndex = nCurNum

    if not _Prop or _nIndex >= TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM:
        print("AddBagItemEle _nIndex >= TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM");
        return null;

    var elem = SBagItem.new(self)
    elem.CopyFrom(_Prop)
    if _nIndex < nCurNum:
        for i in range(nCurNum-1, -1, -1):
            self.m_BagItem[i] = self.m_BagItem[i - 1]
            self.m_BagItem[i].nIndex = i
    self.m_BagItem[_nIndex] = elem
    self.m_nBagItemCount = nCurNum + 1
    elem_add.emit(self, null, elem, _nIndex)

func DelBagItem(_nIndex):
    if _nIndex < 0 or _nIndex >= self.m_nBagItemCount:
        return
    
    self.m_nBagItemCount = self.m_nBagItemCount - 1
    if _nIndex != self.m_nBagItemCount:
        self.m_BagItem[_nIndex] = self.m_BagItem[self.m_nBagItemCount]

    # var nLastDataID = self.m_BagItem[self.m_nBagItemCount]
    var elem = self.m_BagItem[_nIndex]
    for i in range(_nIndex + 1, self.m_nBagItemCount - 1):
        self.m_BagItem[i - 1] = self.m_BagItem[i]
        self.m_BagItem[i - 1].nIndex = i - 1
    self.m_BagItem[self.m_nBagItemCount - 1] = null
    elem_del.emit(self, elem, null, _nIndex)


func CopyFrom(_pOther):
    self.m_nBagItemCount = _pOther.m_nBagItemCount
    for i in range(_pOther.m_nBagItemCount):
        self.m_BagItem[i] = SBagItem.new(self)
        self.m_BagItem[i].CopyFrom(_pOther.m_BagItem[i])

func UnPackField(_fieldId, _bufferStream, _varLen):
    var elemCount = self.m_nBagItemCount
    if _fieldId < 0 or _fieldId > TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM:
        # var szLog = string.format("CBagItemArray.UnPackField Error :\
        #  _fieldId(%d) < 0 or _fieldId(%d) > self.MaxBagItemEleCount()(%d)",
        #  _fieldId, _fieldId, TableCommonDefine.MaxRowElem.MAX_COUNT_BAGITEM)
        return false
    var elem = null
    var old = null
    if self.m_BagItem[_fieldId] != null:
        elem = self.m_BagItem[_fieldId]
        old = SBagItem.new( self )
        old.CopyFrom( elem )
    else:
        elem = SBagItem.new(self)
        self.m_BagItem[_fieldId] = elem
        self.m_BagItem[_fieldId].nIndex = _fieldId

    if elemCount <= _fieldId:
        self.m_nBagItemCount = _fieldId + 1

    elem.Update(_bufferStream, _fieldId )
    elem_update.emit(self, old, elem, _nIndex)
    return true

func AddField(_fieldId, _bufferStream):
    var elem = SBagItem.new(self)
    elem.UnPack(_bufferStream, true )
    elem.nIndex = _fieldId
    if null == self.m_BagItem[_fieldId]:
        self.m_BagItem[_fieldId] = elem
    else:
        var uuid = elem.m_UUID;
        for index in range(self.m_nBagItemCount, _fieldId+1, -1):
            self.m_BagItem[index] = self.m_BagItem[index- 1]
            self.m_BagItem[index].m_UUID = uuid + index - _fieldId
            self.m_BagItem[index].nIndex = index
        self.m_BagItem[_fieldId] = elem;
        self.m_BagItem[_fieldId].nIndex = _fieldId

    self.m_nBagItemCount = self.m_nBagItemCount + 1;
    elem_add.emit(self, null, elem, _fieldId)

func DelField(_fieldId ):
    if self.m_BagItem[_fieldId] == null:
        return 
    
    self.m_nBagItemCount = self.m_nBagItemCount - 1
    var elem = self.m_BagItem[_fieldId]
    if _fieldId != self.m_nBagItemCount:
        var uuid = self.m_BagItem[_fieldId].m_UUID;
        self.m_BagItem[_fieldId] = self.m_BagItem[self.m_nBagItemCount]
        self.m_BagItem[_fieldId].m_UUID = uuid
        self.m_BagItem[_fieldId].nIndex = _fieldId

    self.m_BagItem[self.m_nBagItemCount] = null
    elem_del.emit(self, elem, null, _fieldId)   

func Filter( funFilter ):
    var tblItems = []
    for i in range(self.m_nBagItemCount-1):
        if funFilter.call(self.m_BagItem[i], i):
            tblItems.append(self.m_BagItem[i])
    return tblItems

func QueryByMaskID(MaskID):
    var nCnt = self.m_nBagItemCount
    for i in range(nCnt-1):
        var curElem = self.m_BagItem[i]
        if curElem != null :
            if curElem.m_MaskID == MaskID :
                return curElem
    return null

func QueryByItemUUID(ItemUUID):
    var nCnt = self.m_nBagItemCount
    for i in range(nCnt-1):
        var curElem = self.m_BagItem[i]
        if curElem != null :
            if curElem.m_MaskID > 0 and curElem.m_ItemUUID == ItemUUID :
                return curElem
    return null

func QueryAllDataByItemID(ItemID):
    var nCnt = self.m_nBagItemCount
    var tblData = []
    for i in range(nCnt - 1):
        var curElem = self.m_BagItem[i]
        if curElem != null:
            if curElem.m_MaskID > 0 and curElem.m_ItemID == ItemID :
                tblData.append(curElem)
    return tblData

